<template>
  <el-dialog
    :title="title"
    v-model="dialogVisible"
    width="800px"
    append-to-body
    destroy-on-close
    @closed="handleClosed"
    v-if="dialogVisible"
  >
    <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="漏洞名称" prop="title">
            <el-input v-model="form. title" placeholder="请输入漏洞名称" />
          </el-form-item>
        </el-col>
      </el-row>
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="漏洞来源" prop="source">
            <el-select
              v-model="form.source"
              placeholder="请选择漏洞来源"
              style="width: 100%"
            >
              <el-option
                v-for="value in sourceList"
                :key="value"
                :label="value"
                :value="value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="漏洞类型" prop="vuln_type">
            <el-select
              v-model="form.vuln_type"
              placeholder="请选择漏洞类型"
              style="width: 100%"
            >
              <el-option
                v-for="item in vulnTypeList"
                :key="item"
                :label="item"
                :value="item"
              >
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="产品类型" prop="product_type">
             <el-select
             v-model="form.product_type"
             placeholder="请选择产品类型"             
             style="width: 100%"
             >
             <el-option
             v-for="(value, key) in product_type"
             :key="value"
             :label="value"
             :value="value"
             />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="数据源" prop="is_standard">
            <el-select
            v-model="form.is_standard"
            placeholder="数据源"
            style="width: 100%"
          >
            <el-option label="预备库" :value="0" />
            <el-option label="标准库" :value="1" />
          </el-select>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="CVE编号" prop="cve_id">
            <el-input v-model="form.cve_id" placeholder="请输入CVE编号" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="CNVD编号" prop="cnvd_id">
            <el-input v-model="form.cnvd_id" placeholder="请输入CNVD编号" />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="危害等级" prop="level">
            <el-select
              v-model="form.level"
              placeholder="请选择危害等级"
              style="width: 100%"
            >
              <el-option
                v-for="(value, key) in levelList"
                :key="key"
                :label="key"
                :value="key"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="漏洞评分" prop="score">
            <el-input-number
              v-model="form.score"
              :min="0"
              :max="10"
              :precision="1"
              style="width: 100%"
            />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="厂商" prop="vendor">
            <el-input v-model="form.vendor" placeholder="请输入厂商名称" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="发布时间" prop="publish_time">
            <el-date-picker
              v-model="form.publish_time"
              type="datetime"
              placeholder="请选择发布时间"
              value-format="YYYY-MM-DD HH:mm:ss"
            />
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="产品列表" prop="product_list">
            <el-input
              type="textarea"
              v-model="form.product_list"
              placeholder="请输入产品列表,多个产品用逗号隔开"
              rows="2"
            />
          </el-form-item>
        </el-col>
      </el-row>

      <el-form-item label="漏洞描述" prop="description">
        <el-input
          type="textarea"
          v-model="form.description"
          placeholder="请输入漏洞描述"
          rows="2"
        />
      </el-form-item>

      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="poc列表" prop="poc_files">
            <el-upload
              ref="upload"
              :multiple="true"
              :auto-upload="false"
              :file-list="fileList"
              :before-upload="beforeUpload"
              @change="handleFileChange"
              @remove="handleFileRemove"
            >
              <el-button type="primary" icon="Upload">选择文件</el-button>
              <div slot="tip" class="el-upload__tip" style="margin-left: 10px;">
                poc仅支持多文件文本上传
              </div>
            </el-upload>
          </el-form-item>
        </el-col>
      </el-row>

      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="漏洞危害" prop="vuln_danger">
            <el-input
              type="textarea"
              v-model="form.vuln_danger"
              placeholder="请输入漏洞危害"
              rows="2"
            />
          </el-form-item>
        </el-col>
        </el-row>
        <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="漏洞利用" prop="vuln_use">
            <el-input
              type="textarea"
              v-model="form.vuln_use"
              placeholder="简要描述如何利用此漏洞"
              rows="2"
            />
          </el-form-item>
        </el-col>
      </el-row>

      <el-form-item label="漏洞修复建议" prop="vuln_patch">
        <el-input
          type="textarea"
          v-model="form.vuln_patch"
          placeholder="请输入漏洞修复建议"
          rows="2"
        />
      </el-form-item>

      <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="漏洞cvss" prop="cvss">
            <el-input
              v-model="form.cvss"
              placeholder="请输入漏洞cvss"
              rows="2"
            />
          </el-form-item>
        </el-col>
        </el-row>
        <el-row :gutter="20">
        <el-col :span="24">
          <el-form-item label="漏洞cwe" prop="cwe">
            <el-input v-model="form.cwe" placeholder="请输入漏洞cwe" rows="2" />
          </el-form-item>
        </el-col>
      </el-row>

      <el-form-item label="漏洞cwe描述" prop="cwe_description">
        <el-input
          type="textarea"
          v-model="form.cwe_description"
          placeholder="请输入漏洞cwe描述"
          rows="2"
        />
      </el-form-item>
      <el-form-item label="漏洞参考文献" prop="vuln_references">
        <el-input
          type="textarea"
          v-model="form.vuln_references"
          placeholder="请输入漏洞参考文献,多个参考文献用逗号隔开"
          rows="2"
        />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">取 消</el-button>
        <el-button type="primary" @click="handleSubmit" :loading="submitLoading"
          >确 定</el-button
        >
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, computed, watch } from 'vue';
import { ElMessage } from 'element-plus';
import {
  getProductList
} from "@/api/vulnerability";
/**
 * 定义组件接收的属性
 */
const props = defineProps({
  /**
   * 是否显示弹窗
   */
  visible: {
    type: Boolean,
    default: false,
  },
  /**
   * 弹窗类型: add-新增, edit-编辑
   */
  type: {
    type: String,
    default: "add",
  },
  /**
   * 编辑时传入的漏洞数据
   */
  vulnerabilityData: {
    type: Object,
    default: () => ({}),
  },
  /**
   * 是否正在提交
   */
  loading: {
    type: Boolean,
    default: false,
  },
  /**
   * 漏洞类型列表
   */
  vulnTypeList: {
    type: Array,
    default: () => [],
  },
  /**
   * 漏洞来源列表
   */
  sourceList: {
    type: Array,
    default: () => [],
  },
  /**
   * 危害等级列表
   */
  levelList: {
    type: Object,
    default: () => {},
  },
});

/**
 * 定义组件事件
 */
const emit = defineEmits(["update:visible", "submit", "cancel"]);
// 文件列表 - 存储上传的文件对象
const fileList = ref([]);
// 删除的文件ID列表
const delete_poc_list = ref([]);
// 校验
const beforeUpload = (file)=>{
  // 检查文件类型
      // const isImage = file.name.endsWith('.poc');
      // if (!isImage) {
      //   this.$message.error("poc仅支持多文件文本上传");
      //   return false; // 返回 false 以阻止上传
      // }
 
      return true;
}
// 处理文件添加
const handleFileChange = (uploadFile, uploadFiles) => {  
  fileList.value = uploadFiles.filter(file=>{
    // 检查文件类型
      const isImage = true;// file.raw.name.endsWith('.poc');
      if (isImage) {        
        return true;
      }
  });
};

// 处理文件移除
const handleFileRemove = (file, uploadFiles) => {
  fileList.value = uploadFiles;
  // 编辑模式下删除文件时记录ID
  if (props.type === 'edit' && file.id) {
    delete_poc_list.value.push(file.id);
  }
};
// 表单引用
const formRef = ref(null);
// 弹窗可见状态，用于内部控制
const dialogVisible = computed({
  get: () => props.visible,
  set: (val) => emit("update:visible", val),
});
// 提交按钮加载状态
const submitLoading = computed(() => props.loading);
// 弹窗标题
const title = computed(() => (props.type === "add" ? "新增漏洞" : "编辑漏洞"));

// 表单数据
const form = reactive({});

// 表单验证规则
const rules = {
  title: [{ required: true, message: "请输入漏洞名称", trigger: "blur" }],
  source: [{ required: true, message: "请选择漏洞来源", trigger: "blur" }],
  is_standard: [{ required: true, message: "请选择数据源", trigger: "blur" }],
  product_type: [{ required: true, message: "请选择产品类型", trigger: "blur" }],
  level: [{ required: true, message: "请选择危害等级", trigger: "change" }],
  vuln_type: [{ required: true, message: "请选择漏洞类型", trigger: "change" }],
  description: [{ required: true, message: "请输入漏洞描述", trigger: "blur" }],
  score: [{ required: true, message: "请输入漏洞评分", trigger: "blur" }],
  publish_time: [
    { required: true, message: "请选择发布时间", trigger: "change" },
  ],
};
// 获取产品类型
const product_type = ref([]);
function getProcuctType (){
  getProductList().then(res=>{
    if(res.code === 200){
      product_type.value = res.data.map(item=>{
        return item;
      })
    }
  })
}
getProcuctType();
// 产品列表数据
const productList = ref([]);
// poc列表
const pocList = ref([]);
/**
 * 添加产品版本
 */
const addProduct = () => {
  productList.value.push({
    version: "",
    constraintType: "",
    constraintValue: "",
  });
};
/**
 * 添加poc
 */
const addPoc = () => {
  pocList.value.push({
    type: "",
    poc_exp: "",
  });
};

/**
 * 移除产品版本
 */
const removeProduct = (index) => {
  productList.value.splice(index, 1);
};
/**
 * 移除poc文件
 */
const removePoc = (index) => {
  pocList.value[index].is_delete = 1;
  // pocList.value.splice(index, 1);
};

/**
 * 解析产品列表字符串或数组，处理不同格式
 */
const parseProductList = (data) => {
  // 重置产品列表
  productList.value = [];

  // 如果没有数据返回空数组
  if (!data) return [];

  // 如果是字符串，尝试解析为数组
  let productArray = data;
  if (typeof data === "string") {
    try {
      productArray = JSON.parse(data);
    } catch (e) {
      // 如果不是JSON格式，按逗号分隔处理
      return data.split(",").map((item) => ({
        version: item.trim(),
        constraintType: "",
        constraintValue: "",
      }));
    }
  }

  // 如果不是数组，返回空数组
  if (!Array.isArray(productArray)) return [];

  // 转换为内部格式
  return productArray
    .map((item) => {
      if (typeof item === "string") {
        return {
          version: item,
          constraintType: "",
          constraintValue: "",
        };
      } else if (typeof item === "object") {
        const product = {
          version: item.version || "",
          constraintType: "",
          constraintValue: "",
        };

        if (item.lessThan) {
          product.constraintType = "lessThan";
          product.constraintValue = item.lessThan;
        } else if (item.lessThanOrEqual) {
          product.constraintType = "lessThanOrEqual";
          product.constraintValue = item.lessThanOrEqual;
        }

        return product;
      }
      return null;
    })
    .filter(Boolean);
};

/**
 * 监听漏洞数据变化，用于编辑时回显数据
 */
watch(
  () => props.vulnerabilityData,
  (newVal) => {
    if (newVal && Object.keys(newVal).length) {
      for (const key in newVal) {
        // 判断每个value是否有值
        if (Array.isArray(newVal[key])) {
          if (newVal[key].length > 0) {
            form[key] = newVal[key].join(",");
          }
        } else {
          if (newVal[key]) form[key] = newVal[key];
        }
      }

      // 处理poc文件列表回显
      if (newVal.poc_list && newVal.poc_list.length) {
        fileList.value = newVal.poc_list.map(item => ({
          id: item.id,
          name: item.name || `poc_script_${item.id}.${item.type}`,
          status: 'success',
          url: item.url
        }));
      }
    }
  },
  { immediate: true, deep: true }
);

/**
 * 重置表单
 */
const resetForm = () => {
  if (props.type === "add") {
    Object.keys(form).forEach((key) => {
      form[key] = key === "score" ? 0 : "";
    });
    productList.value = [];
    pocList.value = [];
    fileList.value = [];
  } else {
    for (const key in form) {
      delete form[key];
    }
  }
  // 重置删除文件ID列表
  delete_poc_list.value = [];
  fileList.value = [];
};

/**
 * 监听弹窗类型变化，用于重置表单
 */
watch(
  () => props.type,
  () => {
    resetForm();
  },
  { immediate: true }
);

/**
 * 处理表单提交
 */
const handleSubmit = () => {
  formRef.value.validate((valid) => {
    if (valid) {
      const formattedData = { ...form };
      formattedData.poc_files= fileList.value.filter(item => item.raw !== undefined).map(item=>item.raw);
      // 添加删除文件ID列表
      formattedData.delete_poc_list = [...delete_poc_list.value];
      formattedData.product_list = formattedData?.product_list?.split(",")
      formattedData.vuln_references = formattedData?.vuln_references?.split(",")
      emit("submit", formattedData);
    }
  });
};

/**
 * 处理取消按钮点击
 */
const handleCancel = () => {
  dialogVisible.value = false;
  emit("cancel");
};

/**
 * 处理弹窗关闭
 */
const handleClosed = () => {
  resetForm();
};
</script>

<style lang="scss" scoped>
.upload-demo {
  :deep(.el-upload-list) {
    margin-top: 10px;
  }
}

.product-list-container {
  width: 100%;
  border-radius: 4px;
  padding: 10px;

  .product-item {
    margin-bottom: 10px;
    padding-bottom: 10px;
    border-bottom: 1px dashed #dcdfe6;

    &:last-child {
      border-bottom: none;
    }

    .action-buttons {
      display: flex;
      align-items: center;
      justify-content: center;
      height: 100%;
    }
  }

  .add-product-btn {
    display: flex;
    justify-content: center;
    margin-top: 10px;
  }
}
</style>
